package zjf;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description
 * @Author JiaFu
 * @Date 2023/10/17 0:48
 */
public class HelloRegex {

    public static void main(String[] args) {
//        find();
//        findGroup();
//        replace();
//        replaceSideBySide();
        templateEngine();
    }


    public static void expressionRegex() {
        //<(\w+)>(.＊)</\1>
        //对应的字符串表示
        String regex = "<(\\w+)>(.＊)</\\1>";
        Pattern pattern = Pattern.compile(regex);
    }

    /**
     * 查找 代码寻找所有类似"2023-10-17"这种格式的日期
     */
    public static void find() {
        String regex = "\\d{4}-\\d{2}-\\d{2}";
        Pattern pattern = Pattern.compile(regex);
        String str = "today is 2023-10-17, yesterday is 2023-10-16";
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println("find " + matcher.group()
                    + " position: " + matcher.start() + "-" + matcher.end());
        }
    }

    /**
     * 分组
     */
    public static void findGroup() {
        String regex = "(\\d{4})-(\\d{2})-(\\d{2})";
        Pattern pattern = Pattern.compile(regex);
        String str = "today is 2023-10-17, yesterday is 2023-10-16";
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println("year:" + matcher.group(1)
                    + ", month:" + matcher.group(2) + ", day:" + matcher.group(3));
        }
    }

    /**
     * 替换
     */
    public static void replace() {
        String regex = "\\s+";
        String str = "hello     world         good";
        System.out.println(str.replaceAll(regex, " "));
        System.out.println("----------------------------------------");

        //在replaceAll和replaceFirst中，参数replacement也不是被看作普通的字符串，
        //可以使用美元符号加数字的形式（比如$1）引用捕获分组。我们看个例子：
        regex = "(\\d{4})-(\\d{2})-(\\d{2})";
        str = "today is 2023-10-17.";
        System.out.println(str.replaceFirst(regex, "$1/$2/$3"));
        System.out.println("----------------------------------------");

        //这个例子将找到的日期字符串的格式进行了转换。所以
        //字符'$'在replacement中是元字符，如果需要替换为字符'$'本身，需要使用转义。
        regex = "#";
        str = "#this is a test";
        System.out.println(str.replaceAll(regex, "\\$"));
        System.out.println("----------------------------------------");

        //如果替换字符串是用户提供的，为避免元字符的干扰，可以使用Matcher的如下静态方法将其视为普通字符串
        System.out.println(str.replaceAll(regex, Matcher.quoteReplacement("$")));

        //String的replaceAll和replaceFirst调用的其实是Pattern和Matcher中的方法。
    }

    /**
     * 边查找边替换
     */
    public static void replaceSideBySide() {
        Pattern p = Pattern.compile("cat");
        Matcher m = p.matcher("one cat, two cat, three cat");
        //Matcher内部除了有一个查找位置，还有一个append位置，初始为0
        StringBuffer sb = new StringBuffer();
        int foundNum = 0;
        while (m.find()) {
            m.appendReplacement(sb, "dog");
            foundNum++;
            if (foundNum == 2) {
                break;
            }
        }
        m.appendTail(sb);
        System.out.println(sb.toString());
    }

    /**
     * 模板引擎
     */
    public static void templateEngine() {
        Pattern templatePattern = Pattern.compile("(\\?)");
        String template = "select * from user u where u.name = ? and u.age = ? and u.phone = ? order by u.age";
        List<String> params = Arrays.asList("小王", "22", "13945738534");
        Matcher matcher = templatePattern.matcher(template);
        StringBuffer sb = new StringBuffer();
        int index = 0;
        while (matcher.find()) {
            if (index < params.size()) {
                matcher.appendReplacement(sb, params.get(index));
                index++;
            } else {
                throw new RuntimeException("缺少参数");
            }
        }
        matcher.appendTail(sb);
        System.out.println(sb.toString());
    }

}
